#include "two_player.h"
#include "ui_two_player.h"
#include <time.h>
#include <QMessageBox>
#include <QPainter>
#include <QKeyEvent>
#include <QtDebug>
#include <algorithm>
#include <iostream>
#define Print(v) std::cout << #v << " : " << v << std::endl
//与单人模式基本一致
//定义俄罗斯方块的图案
int block1d[4][4]={
    {0, 0, 0, 0},
    {0, 1, 1, 0},
    {0, 1, 1 ,0},
    {0, 0, 0, 0}
};
//O型
int block2d[4][4]={
    {0, 0, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 0}
};
//I型
int block3d[4][4]={
    {0, 0, 0, 0},
    {0, 1, 1, 1},
    {0, 0, 1, 0},
    {0, 0, 0, 0}
};
//T型
int block4d[4][4]={
    {0, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 0, 0}
};
//L
int block5d[4][4]={
    {0, 0, 1, 0},
    {0, 0, 1, 0},
    {0, 1, 1, 0},
    {0, 0, 0, 0}
};
//J
int block6d[4][4]={
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 0, 0}
};
//S
int block7d[4][4]={
    {0, 0, 1, 0},
    {0, 1, 1, 0},
    {0, 1, 0, 0},
    {0, 0, 0, 0}
};
//Z

void Copy_Block_dou(int Copy_Block[4][4],int Origin_Block[4][4]){
    //Print("copy");
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            Copy_Block[i][j]=Origin_Block[i][j];
        }
    }
}
Two_Player::Two_Player(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Two_Player)
{
    ui->setupUi(this);
    this->setWindowTitle("双人模式");
    //将单人模式的区域扩大至两倍即可
    resize((Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou)*2, (Row_dou*Block_Size_dou+2*Area_Out_dou));
    setMaximumSize((Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou)*2, (Row_dou*Block_Size_dou+2*Area_Out_dou));
    setMinimumSize((Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou)*2, (Row_dou*Block_Size_dou+2*Area_Out_dou));
    Init_Game_dou();
    setFocusPolicy(Qt::StrongFocus);
}

Two_Player::~Two_Player()
{
    delete ui;
}
void Two_Player::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    //游戏边框绘制
    painter.setBrush(QBrush(Qt::white, Qt::SolidPattern));
    //绘制两个对象所在区域的边框
    painter.drawRect(Area_Out_dou,Area_Out_dou,Col_dou*Block_Size_dou,Row_dou*Block_Size_dou);
    painter.drawRect(Area_Out_dou+(Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou),
                     Area_Out_dou, Col_dou*Block_Size_dou,Row_dou*Block_Size_dou);
    //分别绘制下一个方块预告
    painter.setBrush(QBrush(Qt::blue,Qt::SolidPattern));
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(Next_Block_dou[i][j]==1)
            {
                painter.drawRect(Area_Out_dou*3+Col_dou*Block_Size_dou+j*Block_Size_dou,Area_Out_dou+i*Block_Size_dou,
                                 Block_Size_dou,Block_Size_dou);
            }
            if(Next_Block_dou1[i][j]==1)
            {
                painter.drawRect(Area_Out_dou*3+Col_dou*Block_Size_dou+j*Block_Size_dou+
                                 (Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou)
                                 ,Area_Out_dou+i*Block_Size_dou,
                                 Block_Size_dou,Block_Size_dou);
            }
        }
    }
    //分别绘制积分榜
    painter.setPen(Qt::black);
    painter.setFont(QFont("Arial", 14));
    painter.drawText(QRect(Area_Out_dou*3+Col_dou*Block_Size_dou,Area_Out_dou*2+4*Block_Size_dou,
                           4*Block_Size_dou,4*Block_Size_dou),Qt::AlignCenter,"score:"+QString::number(score_dou));
    painter.drawText(QRect(Area_Out_dou*3+Col_dou*Block_Size_dou+(Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou),
                           Area_Out_dou*2+4*Block_Size_dou,
                           4*Block_Size_dou,4*Block_Size_dou),Qt::AlignCenter,"score:"+QString::number(score_dou1));

    //分别绘制图像当中的方块
    for(int i=0;i<Row_dou;i++)
    {
        for(int j=0;j<Col_dou;j++)
        {
            //对正在运动的方块进行绘制
            if(Game_Area_dou[i][j]==1)
            {
                painter.setBrush(QBrush(Qt::red,Qt::SolidPattern));
                painter.drawRect(j*Block_Size_dou+Area_Out_dou,i*Block_Size_dou+Area_Out_dou,Block_Size_dou,Block_Size_dou);
            }
            //对已经落入底部稳定形态的方块进行绘制
            else if(Game_Area_dou[i][j]==2)
            {
                painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));
                painter.drawRect(j*Block_Size_dou+Area_Out_dou,i*Block_Size_dou+Area_Out_dou,Block_Size_dou,Block_Size_dou);
            }
            //同上
            if(Game_Area_dou1[i][j]==1)
            {
                painter.setBrush(QBrush(Qt::red,Qt::SolidPattern));
                painter.drawRect(j*Block_Size_dou+Area_Out_dou+(Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou)
                                 ,i*Block_Size_dou+Area_Out_dou,Block_Size_dou,Block_Size_dou);
            }
            else if(Game_Area_dou1[i][j]==2)
            {
                painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));
                painter.drawRect(j*Block_Size_dou+Area_Out_dou+(Col_dou*Block_Size_dou+Area_Out_dou*4+4*Block_Size_dou)
                                 ,i*Block_Size_dou+Area_Out_dou,Block_Size_dou,Block_Size_dou);
            }
        }
    }
}

//游戏画面的改变
void Two_Player::timerEvent(QTimerEvent *event) {
    if(event->timerId()==Game_Timer_dou){
        //两部分都需要移动
        Block_Move_dou(DOWN_dou);
        Block_Move_dou1(DOWN_dou);
    }
    //刷新画面
    if(event->timerId()==Paint_Timer_dou)
    {
        update();
    }
}

//对按键进行响应
void Two_Player::keyPressEvent(QKeyEvent *event) {
    //Print((int)event->key());
    switch (event->key()) {
    //左侧WASD和空格
    //右侧上下左右和退格
        case Qt::Key_W:
            Block_Move_dou(UP_dou);
            //Print(event->key());
            break;
        case Qt::Key_S:
            Block_Move_dou(DOWN_dou);
            //Print(event->key());
            break;
        case Qt::Key_A:
            Block_Move_dou(LEFT_dou);
            //Print(event->key());
            break;
        case Qt::Key_D:
            Block_Move_dou(RIGHT_dou);
            //Print(event->key());
            break;
        case Qt::Key_Space:
            Block_Move_dou(SPACE_dou);
            //Print(event->key());
            break;
        case Qt::Key_Up:
            Block_Move_dou1(UP_dou);
            break;
        case Qt::Key_Down:
            Block_Move_dou1(DOWN_dou);
            //Print(event->key());
            break;
        case Qt::Key_Left:
            Block_Move_dou1(LEFT_dou);
            //Print(event->key());
            break;
        case Qt::Key_Right:
            Block_Move_dou1(RIGHT_dou);
            //Print(event->key());
        break;
        case Qt::Key_Backspace:
            Block_Move_dou1(SPACE_dou);
            //Print(event->key());
            break;
        default:
            break;
    }
}

void Two_Player::Block_Crate_dou(int Block[4][4], int Block_ID) {
    //Print("crate");
    switch (Block_ID) {
        case 0:
            Copy_Block_dou(Block, block1d);
            break;
        case 1:
            Copy_Block_dou(Block, block2d);
            break;
        case 2:
            Copy_Block_dou(Block, block3d);
            break;
        case 3:
            Copy_Block_dou(Block, block4d);
            break;
        case 4:
            Copy_Block_dou(Block,block5d);
            break;
        case 5:
            Copy_Block_dou(Block, block6d);
            break;
        case 6:
            Copy_Block_dou(Block, block7d);
            break;
        default:
            break;
    }
}

//计算边界用
void Two_Player::Border_Side_dou(int Block[4][4], Border_dou &border) {
    //Print("side");
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            if(Block[i][j]==1)
            {
                border.down_bound_dou=i;
                break;
            }
        }
    }
    for(int i=3;i>=0;i--)
    {
        for (int j = 0; j < 4; j++)
        {
            if(Block[i][j]==1)
            {
                border.up_bound_dou=i;
                break;
            }
        }
    }
    for (int j = 0; j < 4; j++)
    {
        for (int i = 0; i < 4; i++)
        {
            if(Block[i][j]==1)
            {
                border.right_bound_dou=j;
            }
        }
    }
    for (int j = 3; j >=0 ; j--)
    {
        for(int i=0;i<4;i++)
        {
            if(Block[i][j]==1)
            {
                border.left_bound_dou=j;
                break;
            }
        }
    }
}

void Two_Player::Init_Game_dou()
{
    //Print("init");
    for(int i=0;i<Row_dou;i++)
    {
        for(int j=0;j<Col_dou;j++)
        {
            Game_Area_dou[i][j]=0;
            Game_Area_dou1[i][j]=0;
        }
    }
    Down_Time_dou=800;
    Refresh_Time_dou=30;
    //以上数据定义见Two_player.h

    //初始化随机数种子
    srand(time(0));

    //分数清零
    score_dou=0;
    score_dou1=0;

    //运行游戏
    Start_Game_dou();
}

void Two_Player::Block_Reset_dou()
{
    //Print("reset");
    //将当前方块加载进入界面
    Copy_Block_dou(Now_Block_dou, Next_Block_dou);
    Border_Side_dou(Now_Block_dou, Now_border_dou);
    //产生下一个方块
    int Block_ID=rand()%7;
    Block_Crate_dou(Next_Block_dou, Block_ID);
    //设置初始方块坐标，我们设定方块的左上角为坐标定点
    Block_Point_dou start_point;
    start_point.x_pos_dou=Col_dou/2-2;
    start_point.y_pos_dou=0;
    Pos_Block_dou=start_point;
}

void Two_Player::Block_Reset_dou1() {
    //Print("reset");
    Copy_Block_dou(Now_Block_dou1, Next_Block_dou1);
    Border_Side_dou(Now_Block_dou1, Now_border_dou1);
    int Block_ID=rand()%7;
    Block_Crate_dou(Next_Block_dou1, Block_ID);
    Block_Point_dou start_point1;
    start_point1.x_pos_dou=Col_dou/2-2;
    start_point1.y_pos_dou=0;
    Pos_Block_dou1=start_point1;
}
void Two_Player::Start_Game_dou()
{
    //Print("start");
    Game_Timer_dou=startTimer(Down_Time_dou);
    //开始游戏计时
    Paint_Timer_dou=startTimer(Refresh_Time_dou);
    //开启界面刷新计时器
    //产生初始下一个方块
    int Block_ID=rand()%7;
    Block_Crate_dou(Next_Block_dou, Block_ID);
    Block_ID=rand()%7;
    Block_Crate_dou(Next_Block_dou1, Block_ID);
    Block_Reset_dou();
    Block_Reset_dou1();
}

void Two_Player::Game_Over_dou()
{
    //Print("over");
    //结束后停止计时器
    killTimer(Game_Timer_dou);
    killTimer(Paint_Timer_dou);
    QMessageBox::information(this,"failed","game over");
    is_Over_dou = true;
}

void Two_Player::closeEvent(QCloseEvent *event)
{
    Game_Over_dou();
    emit close_dou();
}

//对方块进行旋转
void Two_Player::Block_Revolve_dou(int Block[4][4])
{
    //Print("revolve");
    int Temp_Block[4][4];
    for (int i = 0; i < 4; i++)
    {
        for(int j=0;j<4;j++)
            Temp_Block[3-j][i]=Block[i][j];
    }
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        {
            Block[i][j]=Temp_Block[i][j];
        }
    }
}

//将方块固定在屏幕内
void Two_Player::Block_Stable_dou(int x, int y)
{
    //Print("stable");
    for(int i=Now_border_dou.up_bound_dou;i<=Now_border_dou.down_bound_dou;i++)
    {
        for(int j=Now_border_dou.left_bound_dou;j<=Now_border_dou.right_bound_dou;j++)
        {
            if(Now_Block_dou[i][j]==1)
                Game_Area_dou[y+i][x+j]=2;
        }
    }
}

void Two_Player::Block_Stable_dou1(int x, int y)
{
    //Print("stable");
    for(int i=Now_border_dou1.up_bound_dou;i<=Now_border_dou1.down_bound_dou;i++)
    {
        for(int j=Now_border_dou1.left_bound_dou;j<=Now_border_dou1.right_bound_dou;j++)
        {
            if(Now_Block_dou1[i][j]==1)
                Game_Area_dou1[y+i][x+j]=2;
        }
    }
}
//确认是否方块撞击在其他方块上,并且操作方块运动在坐标上的显示
bool Two_Player::If_Crash_dou(int x,int y,Direction_dou dir)
{
    //Print("crash");
    //用拷贝的临时方块做判断
    int Temp_Block[4][4];
    Copy_Block_dou(Temp_Block,Now_Block_dou);
    Border_dou Temp_Border;
    Border_Side_dou(Temp_Block,Temp_Border);
    //先尝试按照某方向走一格
    switch(dir)
    {
        case UP_dou:
            Block_Revolve_dou(Temp_Block);
            Border_Side_dou(Temp_Block, Temp_Border); //旋转后要重新计算边界
            break;
        case DOWN_dou:
            y += 1;
            break;
        case LEFT_dou:
            x -= 1;
            break;
        case RIGHT_dou:
            x += 1;
            break;
        default:
            break;
    }
    for(int i=Temp_Border.up_bound_dou;i<=Temp_Border.down_bound_dou;i++)
        for(int j=Temp_Border.left_bound_dou;j<=Temp_Border.right_bound_dou;j++)
            if(Game_Area_dou[y+i][x+j]==2&&Temp_Block[i][j]==1||x+Temp_Border.left_bound_dou<0||x+Temp_Border.right_bound_dou>Col_dou-1)
                return true;
    return false;
}

bool Two_Player::If_Crash_dou1(int x,int y,Direction_dou dir)
{
    //Print("crash");
    //用拷贝的临时方块做判断
    int Temp_Block[4][4];
    Copy_Block_dou(Temp_Block,Now_Block_dou1);
    Border_dou Temp_Border;
    Border_Side_dou(Temp_Block,Temp_Border);
    //先尝试按照某方向走一格
    switch(dir)
    {
        case UP_dou:
            Block_Revolve_dou(Temp_Block);
            Border_Side_dou(Temp_Block, Temp_Border); //旋转后要重新计算边界
            break;
        case DOWN_dou:
            y += 1;
            break;
        case LEFT_dou:
            x -= 1;
            break;
        case RIGHT_dou:
            x += 1;
            break;
        default:
            break;
    }
    for (int i = Temp_Border.up_bound_dou; i <= Temp_Border.down_bound_dou; i++)
        for (int j = Temp_Border.left_bound_dou; j <= Temp_Border.right_bound_dou; j++)
            if (Game_Area_dou1[y + i][x + j] == 2 && Temp_Block[i][j] == 1 || x + Temp_Border.left_bound_dou < 0 ||
                x + Temp_Border.right_bound_dou > Col_dou - 1){
                return true;
                Print("crash");
            }
    return false;
}
bool Two_Player::isOver_dou()
{
    return is_Over_dou;
}

//方块移动
void Two_Player::Block_Move_dou(Direction_dou dir)
{
    //Print("move");
    switch (dir) {
        case UP_dou:
            if (If_Crash_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou, UP_dou))
                break;
            //逆时针旋转90度
            Block_Revolve_dou(Now_Block_dou);
            //防止旋转后bug,i和j从0到4重新设置方块
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                    Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] = Now_Block_dou[i][j];
            //重新计算边界
            Border_Side_dou(Now_Block_dou, Now_border_dou);
            break;
        case DOWN_dou:
            //方块到达边界则不再移动
            if (Pos_Block_dou.y_pos_dou + Now_border_dou.down_bound_dou == Row_dou - 1) {
                Block_Stable_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou);
                Block_Reset_dou();
                break;
            }
            //碰撞检测，只计算上下左右边界，先尝试走一格，如果碰撞则稳定方块后跳出
            if (If_Crash_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou, DOWN_dou)) {
                //只有最终不能下落才转成稳定方块
                Block_Stable_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou);
                Block_Reset_dou();
                break;
            }
            //恢复方块上场景,为了清除移动过程中的方块残留
            for (int j = Now_border_dou.left_bound_dou; j <= Now_border_dou.right_bound_dou; j++)
                Game_Area_dou[Pos_Block_dou.y_pos_dou][Pos_Block_dou.x_pos_dou + j] = 0;
            //没有碰撞则下落一格
            Pos_Block_dou.y_pos_dou += 1;
            //方块下降一格，拷贝到场景,注意左右边界
            for (int i = 0; i < 4; i++) //必须是0到4而不是边界索引，考虑到旋转后边界重新计算
                for (int j = Now_border_dou.left_bound_dou; j <= Now_border_dou.right_bound_dou; j++)
                    if (Pos_Block_dou.y_pos_dou + i <= Row_dou - 1 &&
                        Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] != 2) //注意场景数组不越界,而且不会擦出稳定的方块
                        Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] = Now_Block_dou[i][j];
            break;
        case LEFT_dou:
            //到左边界或者碰撞不再往左
            if (Pos_Block_dou.x_pos_dou + Now_border_dou.left_bound_dou == 0 || If_Crash_dou(Pos_Block_dou.x_pos_dou,
                Pos_Block_dou.y_pos_dou, LEFT_dou))
                break;
            //恢复方块右场景,为了清除移动过程中的方块残留
            for (int i = Now_border_dou.up_bound_dou; i <= Now_border_dou.down_bound_dou; i++)
                Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + 3] = 0;
            Pos_Block_dou.x_pos_dou -= 1;
            //方块左移一格，拷贝到场景
            for (int i = Now_border_dou.up_bound_dou; i <= Now_border_dou.down_bound_dou; i++)
                for (int j = 0; j < 4; j++)
                    if (Pos_Block_dou.x_pos_dou + j >= 0 &&
                        Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] != 2) //注意场景数组不越界
                        Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] = Now_Block_dou[i][j];
            break;
        case RIGHT_dou:
            if (Pos_Block_dou.x_pos_dou + Now_border_dou.right_bound_dou == Col_dou - 1 ||
                If_Crash_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou, RIGHT_dou))
                break;
            //恢复方块左场景,为了清除移动过程中的方块残留
            for (int i = Now_border_dou.up_bound_dou; i <= Now_border_dou.down_bound_dou; i++)
                Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou] = 0;
            Pos_Block_dou.x_pos_dou += 1;
            //方块右移一格，拷贝到场景
            for (int i = Now_border_dou.up_bound_dou; i <= Now_border_dou.down_bound_dou; i++)
                for (int j = 0; j < 4; j++)
                    if (Pos_Block_dou.x_pos_dou+ j <= Col_dou - 1 &&
                        Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] != 2) //注意场景数组不越界
                        Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] = Now_Block_dou[i][j];
            break;
        case SPACE_dou: //一次到底
            //一格一格下移，直到不能下移
            while (Pos_Block_dou.y_pos_dou + Now_border_dou.down_bound_dou < Row_dou - 1 &&
                   !If_Crash_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou, DOWN_dou)) {
                //恢复方块上场景,为了清除移动过程中的方块残留
                for (int j = Now_border_dou.left_bound_dou; j <= Now_border_dou.right_bound_dou; j++)
                    Game_Area_dou[Pos_Block_dou.y_pos_dou][Pos_Block_dou.x_pos_dou + j] = 0;
                //没有碰撞则下落一格
                Pos_Block_dou.y_pos_dou += 1;
                //方块下降一格，拷贝到场景,注意左右边界
                for (int i = 0; i < 4; i++) //必须是0到4
                    for (int j = Now_border_dou.left_bound_dou; j <= Now_border_dou.right_bound_dou; j++)
                        if (Pos_Block_dou.y_pos_dou + i <= Row_dou - 1 &&
                            Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] != 2) //注意场景数组不越界,而且不会擦出稳定的方块
                            Game_Area_dou[Pos_Block_dou.y_pos_dou + i][Pos_Block_dou.x_pos_dou + j] = Now_Block_dou[i][j];
            }
            Block_Stable_dou(Pos_Block_dou.x_pos_dou, Pos_Block_dou.y_pos_dou);
            Block_Reset_dou();
            break;
        default:
            break;
    }
    //处理消行，整个场景上面的行依次下移
    int i=Row_dou-1;
    int line_count=0; //记消行数
    while(i>=1)
    {
        bool is_line_full=true;
        for(int j=0;j<Col_dou;j++)
            if(Game_Area_dou[i][j]==0)
            {
                is_line_full=false;
                i--;
                break;
            }
        if(is_line_full)
        {
            for(int k=i;k>=1;k--)
                for(int j=0;j<Col_dou;j++)
                    Game_Area_dou[k][j]=Game_Area_dou[k-1][j];
                line_count++;//每次增加消行的行数
        }
    }
    score_dou+=line_count*10; //得分
    //判断游戏是否结束
    for(int j=0;j<Col_dou;j++)
        if(Game_Area_dou[0][j]==2) //最顶端也有稳定方块
            Game_Over_dou();
}

void Two_Player::Block_Move_dou1(Direction_dou dir1)
{
    //Print("move");
    switch (dir1) {
        case UP_dou:
            if (If_Crash_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou, UP_dou))
                break;
            //逆时针旋转90度
            Block_Revolve_dou(Now_Block_dou1);
            //防止旋转后bug,i和j从0到4重新设置方块
            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                    Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] = Now_Block_dou1[i][j];
            //重新计算边界
            Border_Side_dou(Now_Block_dou1, Now_border_dou1);
            break;
        case DOWN_dou:
            //方块到达边界则不再移动
            if (Pos_Block_dou1.y_pos_dou + Now_border_dou1.down_bound_dou == Row_dou - 1) {
                Block_Stable_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou);
                Block_Reset_dou1();
                break;
            }
            //碰撞检测，只计算上下左右边界，先尝试走一格，如果碰撞则稳定方块后跳出
            if (If_Crash_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou, DOWN_dou)) {
                //只有最终不能下落才转成稳定方块
                Block_Stable_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou);
                Block_Reset_dou1();
                break;
            }
            //恢复方块上场景,为了清除移动过程中的方块残留
            for (int j = Now_border_dou1.left_bound_dou; j <= Now_border_dou1.right_bound_dou; j++)
                Game_Area_dou1[Pos_Block_dou1.y_pos_dou][Pos_Block_dou1.x_pos_dou + j] = 0;
            //没有碰撞则下落一格
            Pos_Block_dou1.y_pos_dou += 1;
            //方块下降一格，拷贝到场景,注意左右边界
            for (int i = 0; i < 4; i++) //必须是0到4而不是边界索引，考虑到旋转后边界重新计算
                for (int j = Now_border_dou1.left_bound_dou; j <= Now_border_dou1.right_bound_dou; j++)
                    if (Pos_Block_dou1.y_pos_dou + i <= Row_dou - 1 &&
                        Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] != 2) //注意场景数组不越界,而且不会擦出稳定的方块
                        Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] = Now_Block_dou1[i][j];
            break;
        case LEFT_dou:
            //到左边界或者碰撞不再往左
            if (Pos_Block_dou1.x_pos_dou + Now_border_dou1.left_bound_dou == 0 || If_Crash_dou(Pos_Block_dou1.x_pos_dou,
                Pos_Block_dou1.y_pos_dou, LEFT_dou))
                break;
            //恢复方块右场景,为了清除移动过程中的方块残留
            for (int i = Now_border_dou1.up_bound_dou; i <= Now_border_dou1.down_bound_dou; i++)
                Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + 3] = 0;
            Pos_Block_dou1.x_pos_dou -= 1;
            //方块左移一格，拷贝到场景
            for (int i = Now_border_dou1.up_bound_dou; i <= Now_border_dou1.down_bound_dou; i++)
                for (int j = 0; j < 4; j++)
                    if (Pos_Block_dou1.x_pos_dou + j >= 0 &&
                        Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] != 2) //注意场景数组不越界
                        Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] = Now_Block_dou1[i][j];
            break;
        case RIGHT_dou:
            if (Pos_Block_dou1.x_pos_dou + Now_border_dou1.right_bound_dou == Col_dou - 1 ||
                If_Crash_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou, RIGHT_dou))
                break;
            //恢复方块左场景,为了清除移动过程中的方块残留
            for (int i = Now_border_dou1.up_bound_dou; i <= Now_border_dou1.down_bound_dou; i++)
                Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou] = 0;
            Pos_Block_dou1.x_pos_dou += 1;
            //方块右移一格，拷贝到场景
            for (int i = Now_border_dou1.up_bound_dou; i <= Now_border_dou1.down_bound_dou; i++)
                for (int j = 0; j < 4; j++)
                    if (Pos_Block_dou1.x_pos_dou+ j <= Col_dou - 1 &&
                        Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] != 2) //注意场景数组不越界
                        Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] = Now_Block_dou1[i][j];
            break;
        case SPACE_dou: //一次到底
            //一格一格下移，直到不能下移
            while (Pos_Block_dou1.y_pos_dou + Now_border_dou1.down_bound_dou < Row_dou - 1 &&
                   !If_Crash_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou, DOWN_dou)) {
                //恢复方块上场景,为了清除移动过程中的方块残留
                for (int j = Now_border_dou1.left_bound_dou; j <= Now_border_dou1.right_bound_dou; j++)
                    Game_Area_dou1[Pos_Block_dou1.y_pos_dou][Pos_Block_dou1.x_pos_dou + j] = 0;
                //没有碰撞则下落一格
                Pos_Block_dou1.y_pos_dou += 1;
                //方块下降一格，拷贝到场景,注意左右边界
                for (int i = 0; i < 4; i++) //必须是0到4
                    for (int j = Now_border_dou1.left_bound_dou; j <= Now_border_dou1.right_bound_dou; j++)
                        if (Pos_Block_dou1.y_pos_dou + i <= Row_dou - 1 &&
                            Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] != 2) //注意场景数组不越界,而且不会擦出稳定的方块
                            Game_Area_dou1[Pos_Block_dou1.y_pos_dou + i][Pos_Block_dou1.x_pos_dou + j] = Now_Block_dou1[i][j];
            }
            Block_Stable_dou1(Pos_Block_dou1.x_pos_dou, Pos_Block_dou1.y_pos_dou);
            Block_Reset_dou1();
            break;
        default:
            break;
    }
    //处理消行，整个场景上面的行依次下移
    int i=Row_dou-1;
    int line_count=0; //记消行数
    while(i>=1)
    {
        bool is_line_full=true;
        for(int j=0;j<Col_dou;j++)
            if(Game_Area_dou1[i][j]==0)
            {
                is_line_full=false;
                i--;
                break;
            }
        if(is_line_full)
        {
            for(int k=i;k>=1;k--)
                for(int j=0;j<Col_dou;j++)
                    Game_Area_dou1[k][j]=Game_Area_dou1[k-1][j];
                line_count++;//每次增加消行的行数
        }
    }
    score_dou1+=line_count*10; //得分
    //判断游戏是否结束
    for(int j=0;j<Col_dou;j++)
        if(Game_Area_dou1[0][j]==2) //最顶端也有稳定方块
            Game_Over_dou();
}
